﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.Storage;
using VBFOOL.MediaPlayer.Core;
using System.Windows.Media.Animation;
using System.IO.IsolatedStorage;
namespace TestPhone
{
    public partial class PlayerPage : PhoneApplicationPage
    {
        public PlayerPage()
        {
            InitializeComponent();
        }
        private void MyPlayer_MediaFailed(object sender, ExceptionRoutedEventArgs e)
        {
            ValueLoop.Stop();
            MessageBox.Show(e.ErrorException.Message);
        }



        TimeSpan StartPosition = TimeSpan.Zero;
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            SystemTray.Opacity = 0.0;
            SystemTray.IsVisible = true;
            if (SystemTray.ProgressIndicator == null)
            {
                SystemTray.ProgressIndicator = new ProgressIndicator();
            }
            SystemTray.ProgressIndicator.IsIndeterminate = true;
            SystemTray.ProgressIndicator.IsVisible = true;
            SystemTray.ProgressIndicator.Text = "努力读取中";
            System.Threading.Tasks.Task.Factory.StartNew(PlayStream);
            if (e.NavigationMode == NavigationMode.New)
            {
                StartPosition = TimeSpan.Zero;
            }
            else if (e.NavigationMode == NavigationMode.Back)
            {
                //System.Threading.Tasks.Task.Factory.StartNew(PlayStream);
            }
        }
        TimeSpan LastPosition;

        void RefreshSubtitle()
        {
            var p2 = DateTime.Now - dtm;
            if (MyPlayer.CurrentState == System.Windows.Media.MediaElementState.Playing)
            {
                if (CurrentSubtitle != null && CurrentSubtitleController != null)
                {
                    var p = MyPlayer.Position;

                    if (CurrentSubtitle.Items.Any(m => (m.TimeCode - p).Duration().TotalMilliseconds > 100))
                    {
                        var items = CurrentSubtitle.Items.Where(m => m.TimeCode >= LastPosition && m.TimeCode <= p).ToArray();
                        foreach (var item in items)
                        {
                            NewSubtitleItem(item);
                        }

                    }
                    LastPosition = p;
                }
            }
            dtm = DateTime.Now;
        }
        VBFOOL.MediaPlayer.Core.Interface.ISubtitleReader CurrentSubtitle = null;
        SubtitleController CurrentSubtitleController = null;
        DateTime dtm = DateTime.Now;
        private void MyPlayer_MediaOpened(object sender, RoutedEventArgs e)
        {
            //MyTimeline = new CustomTimelineCollection(MyPlayer);
            //MyTimeline.MarkerReached += MyTimeline_MarkerReached;
            dtm = DateTime.Now;
            if (src != null)
            {
                if (string.IsNullOrEmpty(src.Source.Title))
                {

                }
                else
                {
                    txtTitle.Text = src.Source.Title;
                }
                if (src.Source.Subtitles.Count() > 0)
                {
                    SubtitleSelect.ItemsSource = src.Source.Subtitles;
                    //System.Threading.Thread.Sleep(1000);
                }

            }
            if (MyPlayer.AudioStreamCount > 0)
            {
                var ats = src.Source.Tracks.Where(m => m.Description.Type == System.Windows.Media.MediaStreamType.Audio).ToList();
                TrackSelect.ItemsSource = ats;
            }
            SystemTray.IsVisible = false;
            SystemTray.ProgressIndicator.IsVisible = false;
            double dt = 0;
            if (MyPlayer.NaturalDuration.HasTimeSpan)
            {
                dt = MyPlayer.NaturalDuration.TimeSpan.TotalSeconds;
            }
            SeekProgress.Maximum = dt;
            //ValueLoop.Interval = TimeSpan.FromMilliseconds(500);
            //ValueLoop.Tick += ValueLoop_Tick;
            //ValueLoop.Start();
            ctk = cts.Token;
            ValueLoopTask = System.Threading.Tasks.Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    try
                    {
                        ctk.ThrowIfCancellationRequested();
                        Dispatcher.BeginInvoke(DoPlayerPosition);
                        System.Threading.Thread.Sleep(1000);
                    }
                    catch (Exception)
                    {
                        break;
                    }
                }
            }, ctk);
            MyPlayer.Position = StartPosition;
            Logs.Add(string.Format("打开视频:{0}", (DateTime.Now - dtm)));
        }

        void MyTimeline_MarkerReached(object sender, MarkerReachedEventArgs e)
        {
            var items = CurrentSubtitle.Items.Where(m => m.TimeCode == e.Marker.Time).ToArray();
            foreach (var item in items)
            {
                NewSubtitleItem(item);
            }
        }
        System.Threading.Tasks.Task ValueLoopTask = null;
        System.Threading.CancellationToken ctk;
        System.Threading.CancellationTokenSource cts = new System.Threading.CancellationTokenSource();
        void ValueLoop_Tick(object sender, EventArgs e)
        {
            DoPlayerPosition();
            //txtMem.Text = string.Format("FPS:{0:F2},Drop:{1:F2},Memory:{2:N}", MyPlayer.RenderedFramesPerSecond, MyPlayer.DroppedFramesPerSecond, Windows.Phone.System.Memory.MemoryManager.ProcessCommittedBytes);
            //Dispatcher.BeginInvoke(RefreshSubtitle);
            //RefreshSubtitle();
        }
        CustomTimelineCollection MyTimeline;
        private void DoPlayerPosition()
        {
            var p = MyPlayer.Position;
            var d = MyPlayer.NaturalDuration.TimeSpan;
            SeekProgress.Value = p.TotalSeconds;
            txtTimePosition.Text = string.Format(@"{0:hh\:mm\:ss} / {1:hh\:mm\:ss}", p, d);
            //RefreshSubtitle();
        }

        private void MyPlayer_MediaEnded(object sender, RoutedEventArgs e)
        {
            if (NavigationService.CanGoBack)
            {
                NavigationService.GoBack();
            }
        }

        protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
            StartPosition = MyPlayer.Position;
            //  ValueLoop.Stop();
            cts.Cancel();
            MyPlayer.Stop();

            fs.Close();
            if (e.NavigationMode == NavigationMode.Back)
            {
                App.PlayingStream = null;
            }
            else if (e.NavigationMode == NavigationMode.New)
            {

            }
            base.OnNavigatingFrom(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            string LogString = string.Join(Environment.NewLine, Logs);
            base.OnNavigatedFrom(e);
        }

        void PlayStream()
        {
            var ms = App.PlayingStream;
            ms.Position = 0;
            LibEBML.Common.Matroska mat = new LibEBML.Common.Matroska(new LibEBML.Common.EBMLDocument(ms));
            int duetime = 150;
            if (IsolatedStorageSettings.ApplicationSettings.Contains("ProcessDueTime"))
            {
                duetime = (int)IsolatedStorageSettings.ApplicationSettings["ProcessDueTime"];
            }
            fs = new VBFOOL.MediaPlayer.MKV.MKVFileSource(mat, TimeSpan.FromMilliseconds(duetime));
            fs.Codecs.Add(new VBFOOL.MediaPlayer.Codecs.H264CodecFactory());
            fs.Codecs.Add(new VBFOOL.MediaPlayer.Codecs.AACCodecFactory());
            fs.Codecs.Add(new VBFOOL.MediaPlayer.Codecs.FlacCodecFactory());
            src = new OpenMediaStreamSource(fs);
            Dispatcher.BeginInvoke(() =>
            {
                MyPlayer.SetSource(src);
                MyPlayer.Play();
            });
        }
        VBFOOL.MediaPlayer.MKV.MKVFileSource fs = null;
        OpenMediaStreamSource src = null;
        System.Windows.Threading.DispatcherTimer ValueLoop = new System.Windows.Threading.DispatcherTimer();

        private void btnPlay_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            switch (MyPlayer.CurrentState)
            {
                case System.Windows.Media.MediaElementState.AcquiringLicense:
                    break;
                case System.Windows.Media.MediaElementState.Buffering:
                    break;
                case System.Windows.Media.MediaElementState.Closed:
                    break;
                case System.Windows.Media.MediaElementState.Individualizing:
                    break;
                case System.Windows.Media.MediaElementState.Opening:
                    break;
                case System.Windows.Media.MediaElementState.Paused:
                    MyPlayer.Play();
                    break;
                case System.Windows.Media.MediaElementState.Playing:
                    if (MyPlayer.CanPause)
                    {
                        MyPlayer.Pause();
                    }
                    break;
                case System.Windows.Media.MediaElementState.Stopped:
                    MyPlayer.Play();
                    break;
                default:
                    break;
            }
        }

        private void Rectangle_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            if (ControlGrid.Visibility == System.Windows.Visibility.Visible)
            {
                ControlGrid.Visibility = System.Windows.Visibility.Collapsed;
            }
            else
            {
                ControlGrid.Visibility = System.Windows.Visibility.Visible;
            }
            HeadGrid.Visibility = ControlGrid.Visibility;
        }

        private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {

        }

        private void MyPlayer_MarkerReached(object sender, System.Windows.Media.TimelineMarkerRoutedEventArgs e)
        {
            Logs.Add(string.Format("触发字幕:{0},{1}", (DateTime.Now - dtm), e.Marker.Time));
            if (e.Marker.Type == "Subtitle" && e.Marker.Text == CurrentSubtitle.Name)
            {
                var items = CurrentSubtitle.Items.Where(m => m.TimeCode == e.Marker.Time).ToArray();
                foreach (var item in items)
                {
                    NewSubtitleItem(item);
                }
            }
        }

        void NewSubtitleItem(VBFOOL.MediaPlayer.Core.Interface.SubtitleItem item)
        {
            if (item == null)
            {
                return;
            }
            var sub = CurrentSubtitleController.NewSubtitleItem(item);
            Logs.Add(string.Format("渲染字幕:{0},{1}", (DateTime.Now - dtm), item.TimeCode));
            //SubtitleGrid.Children.Add(sub);
        }

        private void Menu_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            switch (this.SupportedOrientations)
            {
                case SupportedPageOrientation.Landscape:
                    SettingPivot.Height = this.ActualWidth * 0.5;
                    this.SupportedOrientations = SupportedPageOrientation.Portrait;
                    SettingGrid.Visibility = System.Windows.Visibility.Visible;
                    break;
                case SupportedPageOrientation.Portrait:
                    this.SupportedOrientations = SupportedPageOrientation.Landscape;
                    SettingGrid.Visibility = System.Windows.Visibility.Collapsed;
                    break;
                case SupportedPageOrientation.PortraitOrLandscape:
                    break;
                default:
                    break;
            }
        }
        List<string> Logs = new List<string>();
        private void VideoSizeSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                if (MyPlayer == null)
                {
                    return;
                }
                var m = e.AddedItems[0] as ListPickerItem;
                switch (m.Content.ToString())
                {
                    case "原始大小":
                        MyPlayer.Stretch = System.Windows.Media.Stretch.None;
                        break;
                    case "拉伸":
                        MyPlayer.Stretch = System.Windows.Media.Stretch.Fill;
                        break;
                    case "保持比例":
                        MyPlayer.Stretch = System.Windows.Media.Stretch.Uniform;
                        break;
                    default:
                        break;
                }
            }
        }

        private void TrackSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (MyPlayer != null && MyPlayer.AudioStreamCount > 0)
            {
                var s = TrackSelect.SelectedItem as VBFOOL.MediaPlayer.Core.Interface.IMediaTrack;
                if (s != null)
                {
                    fs.ChangeAudioTrack(s.Description);
                }
            }
        }

        private void SubtitleSelect_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                Logs.Add(string.Format("选择字幕:{0}", (DateTime.Now - dtm).TotalMilliseconds));
                //dtm = DateTime.Now;
                //if (CurrentSubtitle != null)
                //{
                //    CurrentSubtitle.ItemsChanged -= CurrentSubtitle_ItemsChanged;
                //}
                CurrentSubtitle = e.AddedItems[0] as VBFOOL.MediaPlayer.Core.Interface.ISubtitleReader;
                switch (CurrentSubtitle.SubtitleType)
                {
                    case "S_TEXT/UTF8":
                        CurrentSubtitleController = new SRTSubtitleController(SubtitleGrid, CurrentSubtitle);
                        break;
                    case "S_TEXT/ASS":
                        CurrentSubtitleController = new ASSSubtitleController(SubtitleGrid, CurrentSubtitle);
                        //System.Threading.Thread.Sleep(500);
                        break;
                    default:
                        break;
                }
                //if (MyTimeline != null)
                //{
                foreach (var item in CurrentSubtitle.Items)
                {
                    //MyTimeline.Add(new CustomMarker() { Time = item.TimeCode });
                    MyPlayer.Markers.Add(new System.Windows.Media.TimelineMarker() { Time = item.TimeCode, Type = "Subtitle", Text = CurrentSubtitle.Name });
                    //Logs.Add(string.Format("添加字幕:{0}，{1}", (DateTime.Now - dtm).TotalMilliseconds, item.TimeCode));
                    //dtm = DateTime.Now;
                }
                //}

                CurrentSubtitle.ItemsChanged += CurrentSubtitle_ItemsChanged;
            }
        }

        void CurrentSubtitle_ItemsChanged(object sender, VBFOOL.MediaPlayer.Core.Interface.SubtitleChangedEventArgs e)
        {
            Dispatcher.BeginInvoke(() =>
                   {
                       if (e.AddItems.Count > 0)
                       {
                           foreach (var item in e.AddItems)
                           {
                               //MyTimeline.Add(new CustomMarker() { Time = item.TimeCode });
                               MyPlayer.Markers.Add(new System.Windows.Media.TimelineMarker() { Time = item.TimeCode, Type = "Subtitle", Text = CurrentSubtitle.Name });
                               //Logs.Add(string.Format("添加字幕:{0}，{1}", (DateTime.Now - dtm).TotalMilliseconds, item.TimeCode));
                           }
                       }
                   });
        }
        Dictionary<string, VBFOOL.MediaPlayer.Core.Interface.SubtitleItem> Subtitles = new Dictionary<string, VBFOOL.MediaPlayer.Core.Interface.SubtitleItem>();
        private void SeekProgress_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
        {
            var sliderValue = SeekProgress.Value;
            var tm = TimeSpan.FromSeconds(sliderValue);
            MyPlayer.Position = tm;
        }
    }
}